﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.IO;
using System.Text.RegularExpressions;
using System.Diagnostics;

namespace FTUninstaller
{
    public delegate bool RegistryItemScan(string key, QTPUninstaller scan);
    public delegate bool RegistryItemClean(List<string> keys, QTPUninstaller scan);

    public class UpdateProgressEventArgs : EventArgs
    {
        int curValue, maxValue;
        string executionItem;

        public UpdateProgressEventArgs(int value, int max, string item)
        {
            curValue = value;
            maxValue = max;
            executionItem = item;
        }

        public int Value
        {
            get { return curValue; }
            set { curValue = value; }
        }

        public int MaxValue
        {
            get { return maxValue; }
        }

        public object Item
        {
            get { return executionItem; }
        }
    }

    public delegate void UpdateProgressEventHandler(object sender, UpdateProgressEventArgs e);
    public delegate void CleaningCompletedEventHandler(object sender, EventArgs e);

    public partial class QTPUninstaller
    {
        List<string> MatchedCLSIDs;
        List<string> MatchedTypeLibs;
        List<string> MatchedAppIDs;
        List<string> MatchedProgIDs;
        List<string> MatchedIIDs;
        List<string> MatchedInstallerComponents;
        List<string> QTPFilesList;

        public event UpdateProgressEventHandler UpdateProgress;
        public event CleaningCompletedEventHandler CleaningCompleted;


        protected virtual void OnUpdateProgress(UpdateProgressEventArgs e)
        {
            if (UpdateProgress != null)
            {
                //Invokes the delegates.
                UpdateProgress(this, e);
            }
        }


        protected virtual void OnCleaningCompleted(EventArgs e)
        {
            if (CleaningCompleted != null)
            {
                CleaningCompleted(this, e);
            }
        }

        public string QTPInstallationPath
        {
            get { return ""; }
        }

        private string mCLSIDPath, mTypeLibPath, mIIDPath, mUninstallPath, mInstallPath, mAppIDPath;

        string PathCLSID { get { return mCLSIDPath; } }
        string PathTypeLib { get { return mTypeLibPath; } }
        string PathIID { get { return mIIDPath; } }
        string PathUninstall { get { return mUninstallPath; } }
        string PathInstall { get { return mInstallPath; } }
        string PathAppID { get { return mAppIDPath; } }

        public QTPUninstaller()
        {
            string sOS64Path = "";
            if (OSVersionInfo.OSBits == OSVersionInfo.SoftwareArchitecture.Bit64)
                sOS64Path = "Wow6432Node\\";

            mCLSIDPath = sOS64Path + "CLSID\\";
            mTypeLibPath = sOS64Path + "TypeLib\\";
            mIIDPath = sOS64Path + "Interface\\";
            mUninstallPath = "SOFTWARE\\" + sOS64Path + @"\Microsoft\Windows\CurrentVersion\Uninstall\";
            mInstallPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\";
            mAppIDPath = sOS64Path + "AppID\\";

            MatchedAppIDs = new List<string>();
            MatchedCLSIDs = new List<string>();
            //MatchedComponentIDs = new List<string>();
            MatchedIIDs = new List<string>();
            MatchedInstallerComponents = new List<string>();
            //MatchedProductIDs = new List<string>();
            MatchedProgIDs = new List<string>();
            MatchedTypeLibs = new List<string>();
            //QTPFilesList = new List<string>();
            QTPFilesList = File.ReadAllLines("QTPFiles.def").ToList();
        }


        public bool IsQTPRelated(string text)
        {
            Regex patternQTP = new Regex("(.*Functional.*Testing.*)|(.*QuickTest.*Professional.*)|(.*Quality.*Center.*)|(.*HP.*Run.*Result.*Viewer.*)|(.*HP.*QuickTest.*)|(.* QTP .*)", RegexOptions.IgnoreCase);
            return patternQTP.IsMatch(text);
        }


        public bool IsQTPDll(string strDLLFile)
        {
            try { return QTPFilesList.Contains(Path.GetFileName(strDLLFile), StringComparer.CurrentCultureIgnoreCase); }
            catch { return false; }
            //return strDLLFile.ToLower().Contains("quicktest") || strDLLFile.ToLower().StartsWith("mic");
        }

        internal void UninstallQTP()
        {
            this.MatchedInstallerComponents.AddRange(PerformScan(Registry.LocalMachine.OpenSubKey(this.PathInstall).GetSubKeyNames(), KeyScannerInstalledComponent));
            PerformClean(this.MatchedInstallerComponents, KeyCleanerInstalledComponents);

            this.MatchedTypeLibs.AddRange(PerformScan(Registry.ClassesRoot.OpenSubKey(this.PathTypeLib).GetSubKeyNames(), KeyScannerTypeLib));
            this.MatchedProgIDs.AddRange(PerformScan(Registry.ClassesRoot.GetSubKeyNames(), KeyScannerProgID));
            this.MatchedCLSIDs.AddRange(PerformScan(Registry.ClassesRoot.OpenSubKey(this.PathCLSID).GetSubKeyNames(), KeyScannerCLSID));
            this.MatchedIIDs.AddRange(PerformScan(Registry.ClassesRoot.OpenSubKey(this.PathIID).GetSubKeyNames(), KeyScannerIID));
            this.MatchedAppIDs.AddRange(PerformScan(Registry.ClassesRoot.OpenSubKey(this.PathAppID).GetSubKeyNames(), KeyScannerAppID));

            PerformClean(this.MatchedAppIDs, KeyCleanerAppID);
            PerformClean(this.MatchedTypeLibs, KeyCleanerTypeLib);
            PerformClean(this.MatchedIIDs, KeyCleanerIID);
            PerformClean(this.MatchedCLSIDs, KeyCleanerCLSID);
            PerformClean(this.MatchedProgIDs, KeyCleanerProgID);
            OnCleaningCompleted(EventArgs.Empty);
        }
    }
}
